package com.raising.modules.sys.service;

import com.google.common.collect.Lists;
import com.raising.StaticParam;
import com.raising.framework.entity.ResultVo;
import com.raising.framework.service.CrudService;
import com.raising.modules.sys.dao.ResourceDao;
import com.raising.modules.sys.dao.RoleDao;
import com.raising.modules.sys.entity.Resource;
import com.raising.modules.sys.entity.Role;
import com.raising.modules.sys.entity.User;
import com.raising.modules.sys.entity.enums.ResourceEnum;
import com.raising.utils.JStringUtils;
import com.raising.utils.UserUtils;
import org.apache.shiro.authz.permission.WildcardPermission;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.*;

/**
 * 资源服务
 * 
 * @author gaoy
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class ResourceService extends CrudService<ResourceDao, Resource> {

	@Autowired
	RoleDao roleDao;

	/**
	 * 获取权限标识
	 * @param resourceIds
	 * @return
	 */
	public Set<String> findPermissions(Set<String> resourceIds) {
		Set<String> permissions = new HashSet<String>();
		List<Resource> resources = dao.getResources(resourceIds);
		for (int i=0;i<resources.size();i++) {
			Resource resource = resources.get(i);
			if (resource != null
					&& !StringUtils.isEmpty(resource.getPermission())) {
				permissions.add(resource.getPermission());
			}
		}
		return permissions;
	}

	/**
	 * 获取菜单
	 * @param permissions
	 * @return
	 */
	public List<Resource> findMenus(Set<String> permissions) {
		Resource resourceParam = new Resource();
		resourceParam.setStatus(StaticParam.VALID_STRING);
		List<Resource> allResources = dao.getList(resourceParam);
		List<Resource> menus = new ArrayList<Resource>();
		for (Resource resource : allResources) {
			if (resource.isRootNode()) {
				continue;
			}
			if (resource.getType() != ResourceEnum.menu) {
				continue;
			}
			if (!hasPermission(permissions, resource)) {
				continue;
			}
			menus.add(resource);
		}
		return menus;
	}
	/**
	 * 根据角色获取所有菜单
	 * @author GaoYuan
	 * @datetime 2018/2/27 上午11:34
	 */
	public List<Resource> getMenusByIds(String ids) {
		return dao.getMenusByIds(ids);
	}

	/**
	 * 获取组合好的菜单
	 * @author GaoYuan
	 * @date 2018/11/21 下午5:42
	 */
	public ResultVo getMyMenusByUserId() throws Exception {
		User user = UserUtils.getLoginUser();
		List<Role> roles = roleDao.getRoles(user.getRoleIds().toArray(new String[0]));
		String menuss = "";
		Set<String> menuSet = new HashSet<>();
		for(Role role:roles){
			String roleResourceIds = role.getResourceIdsStr();
			String[] roleResourceAttr = roleResourceIds.split(",");
			for(int i=0;i<roleResourceAttr.length;i++){
				if(JStringUtils.isNotBlank(roleResourceAttr[i])){
					menuSet.add(roleResourceAttr[i]);
				}
			}
		}
		for(String str: menuSet){
			menuss = menuss + "," + str;
		}
		if(menuss.startsWith(",")){
			menuss = menuss.substring(1);
		}
		// 这里应该根据角色查询菜单，而不应该根据权限查询菜单
		List<Resource> menus = dao.getMenusByIds(menuss);

		//做拼接
		List<Resource> menus_result = Lists.newArrayList();
		for(Resource resource:menus){
			//找出一级菜单
			if("1".equals(resource.getParentId())){
				//找出二级菜单
				List<Resource> resources2_list = Lists.newArrayList();
				for(Resource resource2:menus){
					if(resource.getId().equals(resource2.getParentId())){
						//找出三级菜单
						List<Resource> resources3_list = Lists.newArrayList();
						for(Resource resource3:menus){
							if(resource2.getId().equals(resource3.getParentId())){
								//找出四级级菜单
								List<Resource> resources4_list = Lists.newArrayList();
								for(Resource resource4:menus){
									if(resource3.getId().equals(resource4.getParentId())){
										resources4_list.add(resource4);
									}
								}
								if( resources4_list!=null && resources4_list.size()>0 ){
									resource3.setChild(resources4_list);
								}
								resources3_list.add(resource3);
							}
						}
						if( resources3_list!=null && resources3_list.size()>0 ){
							resource2.setChild(resources3_list);
						}
						resources2_list.add(resource2);
					}
				}
				if( resources2_list!=null && resources2_list.size()>0 ){
					resource.setChild(resources2_list);
				}
				menus_result.add(resource);
			}
		}
		return ResultVo.success().data(menus_result);
	}

	/**
	 * 获取角色菜单
	 * @param permissions
	 * @return
	 */
	public List<Resource> findRoleMenus(Set<String> permissions) throws Exception{
		List<Resource> allResources = dao.getList(null);
		List<Resource> menus = new ArrayList<Resource>();
		for (Resource resource : allResources) {
			if (resource.isRootNode()) {
				continue;
			}
			if (!hasPermission(permissions, resource)) {
				continue;
			}
			menus.add(resource);
		}
		return menus;
	}

	private boolean hasPermission(Set<String> permissions, Resource resource) {
		if (StringUtils.isEmpty(resource.getPermission())) {
			return true;
		}
		for (String permission : permissions) {
			WildcardPermission p1 = new WildcardPermission(permission);
			WildcardPermission p2 = new WildcardPermission(
					resource.getPermission());
			if (p1.implies(p2) || p2.implies(p1)) {
				return true;
			}
		}
		return false;
	}

	/**
	 * 查询是否存在子节点
	 * @param id
	 * @return
	 */
	public int findNext(String id){
		return dao.findNext(id);
	}

}
